package com.fanxuankai.ksql.function.util;

import java.sql.Date;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.function.Consumer;

/**
 * java.sql.Date 工具类
 * 兼容 fromLogical 问题: 时分秒毫秒设置为 0, 时区设置为 UTC
 *
 * @author fanxuankai
 * @see org.apache.kafka.connect.data.Date#fromLogical(org.apache.kafka.connect.data.Schema, java.util.Date)
 */
public class DateUtils {
    private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

    /**
     * 小于工作时间减一天
     *
     * @param time time
     * @return /
     */
    public static Date workHoursDate(long time, int workHours) {
        return DateUtils.convert(time, calendar -> {
            if (calendar.get(Calendar.HOUR_OF_DAY) < workHours) {
                calendar.add(Calendar.DATE, -1);
            }
        }, null);
    }

    /**
     * 小于工作时间减一天, 再取该年第一天
     *
     * @param time time
     * @return /
     */
    public static Date workHoursFirstDayOfYear(long time, int workHours) {
        return DateUtils.convert(time, calendar -> {
            if (calendar.get(Calendar.HOUR_OF_DAY) < workHours) {
                calendar.add(Calendar.DATE, -1);
            }
        }, calendar -> calendar.set(Calendar.DAY_OF_YEAR, 1));
    }

    /**
     * 小于工作时间减一天, 再取该月第一天
     *
     * @param time time
     * @return /
     */
    public static Date workHoursFirstDayOfMonth(long time, int workHours) {
        return DateUtils.convert(time, calendar -> {
            if (calendar.get(Calendar.HOUR_OF_DAY) < workHours) {
                calendar.add(Calendar.DATE, -1);
            }
        }, calendar -> calendar.set(Calendar.DAY_OF_MONTH, 1));
    }

    /**
     * 该年第一天
     *
     * @param time time
     * @return /
     */
    public static Date firstDayOfYear(long time) {
        return convert(time, null, calendar -> calendar.set(Calendar.DAY_OF_YEAR, 1));
    }

    /**
     * 该月第一天
     *
     * @param time time
     * @return /
     */
    public static Date firstDayOfMonth(long time) {
        return convert(time, null, calendar -> calendar.set(Calendar.DAY_OF_MONTH, 1));
    }

    /**
     * 转 java.sql.Date, 无时分秒毫秒处理
     *
     * @param time time
     * @return /
     */
    public static Date toDate(long time) {
        return convert(time, null, null);
    }

    /**
     * 转 java.sql.Date, 无时分秒毫秒处理
     *
     * @param time time
     * @return /
     */
    public static Date convert(long time, Consumer<Calendar> before, Consumer<Calendar> after) {
        Calendar defaultCalendar = Calendar.getInstance();
        defaultCalendar.setTimeInMillis(time);
        if (before != null) {
            before.accept(defaultCalendar);
        }
        Calendar utc = Calendar.getInstance(UTC);
        utc.set(defaultCalendar.get(Calendar.YEAR), defaultCalendar.get(Calendar.MONTH), defaultCalendar.get(Calendar.DATE));
        utc.set(Calendar.HOUR_OF_DAY, 0);
        utc.set(Calendar.MINUTE, 0);
        utc.set(Calendar.SECOND, 0);
        utc.set(Calendar.MILLISECOND, 0);
        if (after != null) {
            after.accept(utc);
        }
        return new Date(utc.getTimeInMillis());
    }
}
